home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / programming / c / amigacc68k.lha / cc68k / stmt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-02  |  12.5 KB  |  432 lines

  1. #include        "stdio.h"
  2. #include        "c.h"
  3. #include        "expr.h"
  4. #include        "gen.h"
  5. #include        "cglbdec.h"
  6.  
  7.  
  8. /*
  9.  *    68000 C compiler
  10.  *
  11.  *    Copyright 1984, 1985, 1986 Matthew Brandt.
  12.  *  all commercial rights reserved.
  13.  *
  14.  *    This compiler is intended as an instructive tool for personal use. Any
  15.  *    use for profit without the written consent of the author is prohibited.
  16.  *
  17.  *    This compiler may be distributed freely for non-commercial use as long
  18.  *    as this notice stays intact. Please forward any enhancements or questions
  19.  *    to:
  20.  *
  21.  *        Matthew Brandt
  22.  *        Box 920337
  23.  *        Norcross, Ga 30092
  24.  */
  25.  
  26. /*
  27.  *      the statement module handles all of the possible c statements
  28.  *      and builds a parse tree of the statements.
  29.  *
  30.  *      each routine returns a pointer to a statement parse node which
  31.  *      reflects the statement just parsed.
  32.  */
  33.  
  34. struct snode    *statement();   /* forward declaration */
  35.  
  36. struct snode    *whilestmt()
  37. /*
  38.  *      whilestmt parses the c while statement.
  39.  */
  40. {       struct snode    *snp;
  41.         snp =(struct snode *) xalloc(sizeof(struct snode));
  42.         snp->stype = st_while;
  43.         getsym();
  44.         if( lastst != openpa )
  45.                 error(ERR_EXPREXPECT);
  46.         else    {
  47.                 getsym();
  48.                 if( expression(&(snp->exp)) == 0 )
  49.                         error(ERR_EXPREXPECT);
  50.                 needpunc( closepa );
  51.                 snp->s1 = statement();
  52.                 }
  53.         return snp;
  54. }
  55.  
  56. struct snode    *dostmt()
  57. /*
  58.  *      dostmt parses the c do-while construct.
  59.  */
  60. {       struct snode    *snp;
  61.         snp =(struct snode *) xalloc(sizeof(struct snode));
  62.         snp->stype = st_do;
  63.         getsym();
  64.         snp->s1 = statement();
  65.         if( lastst != kw_while )
  66.                 error(ERR_WHILEXPECT);
  67.         else    {
  68.                 getsym();
  69.                 if( lastst != openpa )
  70.                         error(ERR_EXPREXPECT);
  71.                 else    {
  72.                         getsym();
  73.                         if( expression(&(snp->exp)) == 0 )
  74.                                 error(ERR_EXPREXPECT);
  75.                         needpunc(closepa);
  76.                         }
  77.                 if( lastst != end )
  78.                         needpunc( semicolon );
  79.                 }
  80.         return snp;
  81. }
  82.  
  83.  
  84. /*
  85.  *      forstmt parses the c for construct.
  86.  *    DAW: little changes had to be added to get compiled with the SAS/C 6.50
  87.  *         (the replaced original lines were put between comment markers).
  88.  *
  89.  */
  90. struct snode    *forstmt()
  91. {       struct snode    *snp;
  92.         snp =(struct snode *) xalloc(sizeof(struct snode));
  93.         getsym();
  94.         needpunc(openpa);
  95.         /* if( expression(&((struct enode *)(snp->label))) == 0 ) */
  96.         if( expression(&(snp->label)) == 0 )
  97.                 snp->label = 0;
  98.         needpunc(semicolon);
  99.         snp->stype = st_for;
  100.         if( expression(&(snp->exp)) == 0 )
  101.                 snp->exp = 0;
  102.         needpunc(semicolon);
  103.         /* if( expression(&((struct enode *)(snp->s2))) == 0 ) */
  104.         if( expression(&(snp->s2)) == 0 )
  105.                 snp->s2 = 0;
  106.         needpunc(closepa);
  107.         snp->s1 = statement();
  108.         return snp;
  109. }
  110.  
  111. struct snode    *ifstmt()
  112. /*
  113.  *      ifstmt parses the c if statement and an else clause if
  114.  *      one is present.
  115.  */
  116. {       struct snode    *snp;
  117.         snp =(struct snode *) xalloc(sizeof(struct snode));
  118.         snp->stype = st_if;
  119.         getsym();
  120.         if( lastst != openpa )
  121.                 error(ERR_EXPREXPECT);
  122.         else    {
  123.                 getsym();
  124.                 if( expression(&(snp->exp)) == 0 )
  125.                         error(ERR_EXPREXPECT);
  126.                 needpunc( closepa );
  127.                 snp->s1 = statement();
  128.                 if( lastst == kw_else ) {
  129.                         getsym();
  130.                         snp->s2 = statement();
  131.                         }
  132.                 else
  133.                         snp->s2 = 0;
  134.                 }
  135.         return snp;
  136. }
  137.  
  138. struct snode    *casestmt()
  139. /*
  140.  *      cases are returned as seperate statements. for normal
  141.  *      cases label is the case value and s2 is zero. for the
  142.  *      default case s2 is nonzero.
  143.  */
  144. {       struct snode    *snp;
  145.         struct snode    *head, *tail;
  146.         snp =(struct snode *) xalloc(sizeof(struct snode));
  147.         if( lastst == kw_case ) {
  148.                 getsym();
  149.                 snp->s2 = 0;
  150.                 snp->stype = st_case;
  151.                 snp->label =(int *) intexpr();
  152.                 }
  153.         else if( lastst == kw_default) {
  154.                 getsym();
  155.                 snp->s2 =(struct snode *) 1;
  156.                 }
  157.         else    {
  158.                 error(ERR_NOCASE);
  159.                 return 0;
  160.                 }
  161.         needpunc(colon);
  162.         head = 0;
  163.         while( lastst != end &&
  164.                 lastst != kw_case &&
  165.                 lastst != kw_default ) {
  166.                 if( head == 0 )
  167.                         head = tail = statement();
  168.                 else    {
  169.                         tail->next = statement();
  170.                         if( tail->next != 0 )
  171.                                 tail = tail->next;
  172.                         }
  173.                 tail->next = 0;
  174.                 }
  175.         snp->s1 = head;
  176.         return snp;
  177. }
  178.  
  179. int     checkcases(head)
  180. /*
  181.  *      checkcases will check to see if any duplicate cases
  182.  *      exist in the case list pointed to by head.
  183.  */
  184. struct snode    *head;
  185. {
  186.     struct snode    *top, *cur;
  187.     cur = top = head;
  188.     while( top != 0 )
  189.     {
  190.         cur = top->next;
  191.         while( cur != 0 )
  192.         {
  193.             if( (!(cur->s1 || cur->s2) && cur->label == top->label)
  194.                 || (cur->s2 && top->s2) )
  195.             {
  196.                 printf(" duplicate case label %d\n",cur->label);
  197.                 return 1;
  198.             }
  199.             cur = cur->next;
  200.         }
  201.         top = top->next;
  202.     }
  203.     return 0;
  204. }
  205.  
  206. struct snode    *switchstmt()
  207. {       struct snode    *snp;
  208.         struct snode    *head, *tail;
  209.         snp =(struct snode *) xalloc(sizeof(struct snode));
  210.         snp->stype = st_switch;
  211.         getsym();
  212.         needpunc(openpa);
  213.         if( expression(&(snp->exp)) == 0 )
  214.                 error(ERR_EXPREXPECT);
  215.         needpunc(closepa);
  216.         needpunc(begin);
  217.         head = 0;
  218.         while( lastst != end ) {
  219.                 if( head == 0 )
  220.                         head = tail = casestmt();
  221.                 else    {
  222.                         tail->next = casestmt();
  223.                         if( tail->next != 0 )
  224.                                 tail = tail->next;
  225.                         }
  226.                 tail->next = 0;
  227.                 }
  228.         snp->s1 = head;
  229.         getsym();
  230.         if( checkcases(head) )
  231.                 error(ERR_DUPCASE);
  232.         return snp;
  233. }
  234.  
  235. struct snode    *retstmt()
  236. {       struct snode    *snp;
  237.         snp =(struct snode *) xalloc(sizeof(struct snode));
  238.         snp->stype = st_return;
  239.         getsym();
  240.         expression(&(snp->exp));
  241.         if( lastst != end )
  242.                 needpunc( semicolon );
  243.         return snp;
  244. }
  245.  
  246. struct snode    *breakstmt()
  247. {       struct snode    *snp;
  248.         snp =(struct snode *) xalloc(sizeof(struct snode));
  249.         snp->stype = st_break;
  250.         getsym();
  251.         if( lastst != end )
  252.                 needpunc( semicolon );
  253.         return snp;
  254. }
  255.  
  256. struct snode    *contstmt()
  257. {       struct snode    *snp;
  258.         snp =(struct snode *) xalloc(sizeof(struct snode));
  259.         snp->stype = st_continue;
  260.         getsym();
  261.         if( lastst != end )
  262.                 needpunc( semicolon );
  263.         return snp;
  264. }
  265.  
  266. struct snode    *exprstmt()
  267. /*
  268.  *      exprstmt is called whenever a statement does not begin
  269.  *      with a keyword. the statement should be an expression.
  270.  */
  271. {       struct snode    *snp;
  272.         snp =(struct snode *) xalloc(sizeof(struct snode));
  273.         snp->stype = st_expr;
  274.         if( expression(&(snp->exp)) == 0 ) {
  275.                 error(ERR_EXPREXPECT);
  276.                 getsym();
  277.                 }
  278.         if( lastst != end )
  279.                 needpunc( semicolon );
  280.         return snp;
  281. }
  282.  
  283. struct snode    *compound()
  284. /*
  285.  *      compound processes a block of statements and forms a linked
  286.  *      list of the statements within the block.
  287.  *
  288.  *      compound expects the input pointer to already be past the
  289.  *      begin symbol of the block.
  290.  */
  291. {       struct snode    *head, *tail;
  292.         head = 0;
  293.         while( lastst != end ) {
  294.                 if( head == 0 )
  295.                         head = tail = statement();
  296.                 else    {
  297.                         tail->next = statement();
  298.                         if( tail->next != 0 )
  299.                                 tail = tail->next;
  300.                         }
  301.                 }
  302.         getsym();
  303.         return head;
  304. }
  305.  
  306. struct snode    *labelstmt()
  307. /*
  308.  *      labelstmt processes a label that appears before a
  309.  *      statement as a seperate statement.
  310.  */
  311. {       struct snode    *snp;
  312.         SYM             *sp;
  313.         snp =(struct snode *) xalloc(sizeof(struct snode));
  314.         snp->stype = st_label;
  315.         if( (sp =(SYM *) search(lastid,lsyms.head)) == 0 ) {
  316.                 sp =(SYM *) xalloc(sizeof(SYM));
  317.                 sp->name =(char *) litlate(lastid);
  318.                 sp->storage_class = sc_label;
  319.                 sp->tp = 0;
  320.                 sp->value.i =(long) nextlabel++;
  321.                 insert(sp,&lsyms);
  322.                 }
  323.         else    {
  324.                 if( sp->storage_class != sc_ulabel )
  325.                         error(ERR_LABEL);
  326.                 else
  327.                         sp->storage_class = sc_label;
  328.                 }
  329.         getsym();       /* get past id */
  330.         needpunc(colon);
  331.         if( sp->storage_class == sc_label ) {
  332.                 snp->label =(int *) sp->value.i;
  333.                 snp->next = 0;
  334.                 return snp;
  335.                 }
  336.         return 0;
  337. }
  338.  
  339. struct snode    *gotostmt()
  340. /*
  341.  *      gotostmt processes the goto statement and puts undefined
  342.  *      labels into the symbol table.
  343.  */
  344. {       struct snode    *snp;
  345.         SYM             *sp;
  346.         getsym();
  347.         if( lastst != id ) {
  348.                 error(ERR_IDEXPECT);
  349.                 return 0;
  350.                 }
  351.         snp =(struct snode *) xalloc(sizeof(struct snode));
  352.         if( (sp =(SYM *) search(lastid,lsyms.head)) == 0 ) {
  353.                 sp =(SYM *) xalloc(sizeof(SYM));
  354.                 sp->name =(char *) litlate(lastid);
  355.                 sp->value.i =(long) nextlabel++;
  356.                 sp->storage_class = sc_ulabel;
  357.                 sp->tp = 0;
  358.                 insert(sp,&lsyms);
  359.                 }
  360.         getsym();       /* get past label name */
  361.         if( lastst != end )
  362.                 needpunc( semicolon );
  363.         if( sp->storage_class != sc_label && sp->storage_class != sc_ulabel)
  364.                 error( ERR_LABEL );
  365.         else    {
  366.                 snp->stype = st_goto;
  367.                 snp->label =(int *) sp->value.i;
  368.                 snp->next = 0;
  369.                 return snp;
  370.                 }
  371.         return 0;
  372. }
  373.  
  374. struct snode    *statement()
  375. /*
  376.  *      statement figures out which of the statement processors
  377.  *      should be called and transfers control to the proper
  378.  *      routine.
  379.  */
  380. {       struct snode    *snp;
  381.         switch( lastst ) {
  382.                 case semicolon:
  383.                         getsym();
  384.                         snp = 0;
  385.                         break;
  386.                 case begin:
  387.                         getsym();
  388.                         snp = compound();
  389.                         return snp;
  390.                 case kw_if:
  391.                         snp = ifstmt();
  392.                         break;
  393.                 case kw_while:
  394.                         snp = whilestmt();
  395.                         break;
  396.                 case kw_for:
  397.                         snp = forstmt();
  398.                         break;
  399.                 case kw_return:
  400.                         snp = retstmt();
  401.                         break;
  402.                 case kw_break:
  403.                         snp = breakstmt();
  404.                         break;
  405.                 case kw_goto:
  406.                         snp = gotostmt();
  407.                         break;
  408.                 case kw_continue:
  409.                         snp = contstmt();
  410.                         break;
  411.                 case kw_do:
  412.                         snp = dostmt();
  413.                         break;
  414.                 case kw_switch:
  415.                         snp = switchstmt();
  416.                         break;
  417.                 case id:
  418.                         while( isspace(lastch) )
  419.                                 getch();
  420.                         if( lastch == ':' )
  421.                                 return labelstmt();
  422.                         /* else fall through to process expression */
  423.                 default:
  424.                         snp = exprstmt();
  425.                         break;
  426.                 }
  427.         if( snp != 0 )
  428.                 snp->next = 0;
  429.         return snp;
  430. }
  431.  
  432.